package com.yootk.servlet;

import jakarta.servlet.AsyncContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.WriteListener;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

/**
 * 异步输出响应
 */
@WebServlet(value = "/async.output", asyncSupported = true) // 默认情况下是不开启异步支持的
public class AsyncWriteServlet extends HttpServlet {

    private class ServletWriteListener implements WriteListener {
        private AsyncContext asyncContext;
        private ServletOutputStream servletOutputStream;

        public ServletWriteListener(AsyncContext asyncContext, ServletOutputStream servletOutputStream) {
            this.asyncContext = asyncContext;
            this.servletOutputStream = servletOutputStream;
        }

        @Override
        public void onWritePossible() throws IOException { // 输出准备就绪执行
            try {
                TimeUnit.SECONDS.sleep(5);  // 模拟延迟
                PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(this.servletOutputStream, "UTF-8"));
                printWriter.print("<h1>www.yootk.com</h1>");
                printWriter.close();
                this.asyncContext.complete();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onError(Throwable throwable) { // 出现异常时执行
        }
    }

    @Override   // 进行GET请求的处理
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        if (req.isAsyncSupported()) { // 判断当前是否支持有异步请求处理能力
            AsyncContext asyncContext = req.startAsync(); // 创建异步处理的上下文对象
            // 一旦项目中得到了Servlet输出流之后，不能够再跳转了
            ServletOutputStream outputStream = resp.getOutputStream(); // 获取输出流
            outputStream.setWriteListener(new ServletWriteListener(asyncContext, outputStream));

        } else {
            resp.getWriter().println("<h1>骚蕊，我还不支持异步请求处理，请放过我吧！</h1>");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
